const { SyncHook, SyncBailHook, SyncLoopHook, SyncWaterfallHook } = require('tapable');
function TestNormal() {
  const hook = new SyncHook(['name']);

  hook.tap('01', (name) => {
    console.log('01 receive:' + name);
    return false;
  });

  hook.tap('02', (name) => {
    console.log('02 receive:' + name);
    return '222';
  });

  hook.tap('03', (name) => {
    console.log('03 receive:' + name);
    return 'name from 03'; // 返回值没有任何影响
  });

  console.log(hook.call('original')); // 返回undefined
}

function TestBail() {
  const hook = new SyncBailHook(['name']);

  hook.tap('01', (name) => {
    console.log('01 receive:' + name);
  });

  hook.tap('02', (name) => {
    console.log('02 receive:' + name);
    return false; // 不是undefined，表示熔断
  });

  hook.tap('03', (name) => {
    console.log('03 receive:' + name);
    return 'name from 03';
  });

  console.log(hook.call('original')); // 熔断的返回值会作为最终的结果
}

function TestLoop() {
  /**
   * loop 是单个回调，自身不断循环，直到返回undefined才不再执行自身
   */
  const hook = new SyncLoopHook(['name']);
  let i = 0;

  hook.tap('01', (name) => {
    if (i < 3) {
      console.log('01 receive:' + name); // 先打印3次
      i++;
      return 'name01:i:' + i; // 返回值意义不大，只要不是undefined就再执行一遍
    }
  });

  hook.tap('02', (name) => {
    if (i < 5) {
      console.log('02 receive:' + name); // 再打印2次
      i++;
      return 'name02:i:' + i;
    }
  });

  hook.tap('03', (name) => {
    if (i < 6) {
      console.log('03 receive:' + name); // 打印一次
      i++;
      return 'name03:i:' + i;
    }
  });

  console.log(hook.call('original')); // 返回undefined
}

function TestWaterfall() {
  const hook = new SyncWaterfallHook(['name']);

  hook.tap('01', (name) => {
    console.log('01 receive:' + name);
    return 'name from 01';
  });

  hook.tap('02', (name) => {
    console.log('02 receive:' + name);
    // return 'name from 02'; // 只要不是undefined，都将作为下一个回调的值。
  });

  hook.tap('03', (name) => {
    console.log('03 receive:' + name);
    return 'name from 03';
  });

  console.log('final:', hook.call('original')); // 最后的返回值，会作为call的结果，这里返回 name from 03
}

// TestNormal();
// TestBail();
// TestLoop();
// TestWaterfall();
